package cn.woblog.android.common.skin.core;

import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import android.R.drawable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.Log;
import cn.woblog.android.common.skin.ThemeInfo;
import cn.woblog.android.common.utils.Logs;
import dalvik.system.PathClassLoader;

public class ThemeManager {
	private static Map<Integer, SoftReference<Integer>> resourceCaches = new LinkedHashMap<Integer, SoftReference<Integer>>();
	private static Map<Integer, SoftReference<Drawable>> resourceDrawableCaches = new LinkedHashMap<Integer, SoftReference<Drawable>>();

	private static enum ValueType {
		COLOR, DIMENSION, DRAWABLE_RESOURCE, DRAWABLE
	};

	private static final String TAG = "ThemeManager";
	private static final String THEME_NAME = "theme_name";
	private static final String KEY_THEME_DEFAULT = "key_theme_default1";
	//	private static final String KEY_THEME_DEFAULT_PACKAGE = "key_theme_default_packages";
	private static final String SKIN_NAME = ".skin";
	//	private static final String APK_FILENAME = "-1.apk";
	//	private static final String APK_DIR = "/data/app/";
	private static final String COLOR_CLASS = ".R$color";
	private static final String DIMENSION_CLASS = ".R$dimen";
	private static final String DRAWABLE_CLASS = ".R$drawable";
	private static Context context;
	private static Context currentThemeContext;
	private static String firstThemePackageName;

	public static Context getContext() {
		return context;
	}

	public static void setContext(Context context) {
		ThemeManager.context = context;
		if (getCurrentThemeId() != null) {
			try {
				if (firstThemePackageName == null) {
					firstThemePackageName = getCurrentThemeId();
				}
				currentThemeContext = context.createPackageContext(getCurrentThemePackage(), Context.CONTEXT_IGNORE_SECURITY);
			} catch (Exception e) {
				e.printStackTrace();
				currentThemeContext = context;
			}
		}
	}

	public static void changeTheme(ThemeInfo info) {
		//		setCurrentThemeId(info.getPackageName());
		setCurrentThemeId(info.getPackageName(), info.getSourceDir());
		setContext(context);
		resourceCaches.clear();
		resourceDrawableCaches.clear();
	}

	public static List<ThemeInfo> getThemes() {
		List<ThemeInfo> themes = new ArrayList<ThemeInfo>();
		List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(0);
		PackageInfo packageInfo = null;
		ThemeInfo tmpInfo = null;
		boolean isFirst = false;
		for (int i = 0; i < packages.size(); i++) {
			packageInfo = packages.get(i);
			if (packageInfo.packageName.startsWith((context.getPackageName() + SKIN_NAME))) {
				tmpInfo = new ThemeInfo();
				if (packageInfo.packageName.equals(getCurrentThemePackage())) {
					tmpInfo.setDefualt(true);
					isFirst = true;
				}
				tmpInfo.setSourceDir(packageInfo.applicationInfo.sourceDir);
				tmpInfo.setTitle(packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString());
				tmpInfo.setPackageName(packageInfo.packageName);
				tmpInfo.setVersionName(packageInfo.versionName);
				tmpInfo.setVersionCode(packageInfo.versionCode);
				Drawable loadIcon = packageInfo.applicationInfo.loadIcon(context.getPackageManager());
				tmpInfo.setAppIcon(loadIcon);
				themes.add(tmpInfo);
			}
		}
		tmpInfo = new ThemeInfo();
		tmpInfo.setTitle("系统自带主题");
		tmpInfo.setPackageName(context.getPackageName());
		if (isFirst) {

		} else {
			tmpInfo.setDefualt(true);
		}
		themes.add(0, tmpInfo);
		return themes;
	}

	//	public static List<ThemeInfo> getThemes() {
	//		List<ThemeInfo> themes = new ArrayList<ThemeInfo>();
	//		String dir = context.getFilesDir().getAbsolutePath() + SKIN_DIR;
	//		File file = new File(dir);
	//		Gson gson = new Gson();
	//		ThemeInfo info = null;
	//		boolean isDefualt = false;
	//		if (file.exists()) {
	//			File[] listFiles = file.listFiles();
	//			for (int i = 0; i < listFiles.length; i++) {
	//				info.setPathName(listFiles[i].getAbsolutePath());
	//				info = gson.fromJson(IOUtils.readString(info.getPathName() + SKIN_INFO_FILENAME), ThemeInfo.class);
	//				if (info.getId().equals(getCurrentThemeId())) {
	//					info.setDefualt(true);
	//					isDefualt = true;
	//				}
	//				themes.add(info);
	//				Log.d(TAG, "skin info " + info.getTitle());
	//			}
	//		}
	//		ThemeInfo themeInfo = new ThemeInfo();
	//		themeInfo.setTitle("系统默认主题");
	//		themeInfo.setId(0 + "");
	//		if (isDefualt) {
	//			themeInfo.setDefualt(true);
	//		}
	//		themes.add(0, themeInfo);
	//		return themes;
	//	}

	private static String getCurrentThemePackage() {
		String[] themeInfo = getThemeInfo();
		if (themeInfo != null) {
			return themeInfo[0];
		}
		return null;
	}

	public static String getCurrentThemeId() {
		String[] themeInfo = getThemeInfo();
		if (themeInfo != null) {
			return themeInfo[1];
		}
		return null;
	}

	private static String[] getThemeInfo() {
		String string = getSharedPreferences().getString(KEY_THEME_DEFAULT, null);
		if (string != null) {
			String[] split = string.split("\\|");

			return split;
		}
		return null;
	}

	//	public static String getCurrentThemePackage() {
	//		return getSharedPreferences().getString(KEY_THEME_DEFAULT_PACKAGE, null);
	//	}

	//	public static boolean setCurrentThemePackage(String str) {
	//		return getSharedPreferences().edit().putString(KEY_THEME_DEFAULT_PACKAGE, str).commit();
	//	}

	public static boolean setCurrentThemeId(String sourceDir, String packname) {
		return getSharedPreferences().edit().putString(KEY_THEME_DEFAULT, sourceDir + "|" + packname).commit();
	}

	public static SharedPreferences getSharedPreferences() {
		return context.getSharedPreferences(THEME_NAME, Context.MODE_PRIVATE);
	}

	public static Drawable getDrawable(int id) {
		return (Drawable) getValue(ValueType.DRAWABLE, id);
	}

	public static int getDimen(int id) {
		return (Integer) getValue(ValueType.DIMENSION, id);
	}

	public static int getColor(int id) {
		return (Integer) getValue(ValueType.COLOR, id);
	}

	@SuppressLint("NewApi")
	private static Object getValue(ValueType type, int id) {
		if (getCurrentThemeId() == null || getCurrentThemePackage().equals(context.getPackageName())) {
			Logs.d(TAG, "get defualt %s by id:%s", type.name(), id);
			return getDefaultValue(type, id);
		}

		if (type == ValueType.DRAWABLE) {
			if (resourceDrawableCaches.get(id) != null) {
				Drawable drawable = resourceDrawableCaches.get(id).get();
				if (drawable != null) {
					return drawable;
				}
			}
		} else {
			if (resourceCaches.get(id) != null) {
				Logs.d(TAG, "get cache %s  by id:%s", type.name(), id);
				//				return resourceCaches.get(id).get();
				Integer integer = resourceCaches.get(id).get();
				if (integer != null) {
					return integer;
				}
			}
		}

		try {
			String colorString = null;
			String color_class_name = null;
			String current_color_class_name = null;
			switch (type) {
			case DIMENSION:
				color_class_name = context.getPackageName() + DIMENSION_CLASS;
				current_color_class_name = currentThemeContext.getPackageName() + DIMENSION_CLASS;
				break;
			case COLOR:
				color_class_name = context.getPackageName() + COLOR_CLASS;
				current_color_class_name = currentThemeContext.getPackageName() + COLOR_CLASS;
				break;
			case DRAWABLE_RESOURCE:
			case DRAWABLE:
				color_class_name = context.getPackageName() + DRAWABLE_CLASS;
				current_color_class_name = currentThemeContext.getPackageName() + DRAWABLE_CLASS;
				break;

			default:
				break;
			}
			Class<?> tempClass = Class.forName(color_class_name);
			Field[] fields = tempClass.getFields();
			int size = fields.length;
			for (int i = 0; i < size; i++) {
				int value = fields[i].getInt(null);
				if (id == value) {
					colorString = fields[i].getName();
					Logs.d(TAG, "find %s string:%s by id:%s", type.name(), colorString, id);
				}
			}

			//		PathClassLoader pathClassLoader = new PathClassLoader("/data/app/cn.woblog.android.test.switchtheme.theme.blue-1.apk", ClassLoader.getSystemClassLoader());
			PathClassLoader pathClassLoader = new PathClassLoader(getCurrentThemeId(), ClassLoader.getSystemClassLoader());
			Class<?> loadClass = pathClassLoader.loadClass(current_color_class_name);
			fields = loadClass.getFields();
			int length = fields.length;
			int tempId = 0;
			Drawable tempDrawable = null;
			for (int i = 0; i < length; i++) {
				if (fields[i].getName().equals(colorString)) {
					tempId = fields[i].getInt(null);
					int tempValue = -1;
					switch (type) {
					case DIMENSION:
						tempValue = getCurrentResource().getDimensionPixelSize(tempId);
						break;
					case COLOR:
						tempValue = getCurrentResource().getColor(tempId);
						break;
					case DRAWABLE_RESOURCE:
						tempValue = tempId;
					case DRAWABLE:
						tempDrawable = getCurrentResource().getDrawable(tempId);
						break;

					default:
						break;
					}
					if (type == ValueType.DRAWABLE) {
						if (tempDrawable != null) {
							resourceDrawableCaches.put(id, new SoftReference<Drawable>(tempDrawable));
							Logs.d(TAG, "find %s string:%s id value:%d drawable:%s", type.name(), colorString, tempId, tempDrawable.toString());
							return tempDrawable;
						}
					} else {
						if (tempValue != -1) {
							resourceCaches.put(id, new SoftReference<Integer>(tempValue));
							Logs.d(TAG, "find %s string:%s id value:%d color:%d", type.name(), colorString, tempId, tempValue);
							return tempValue;
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			Logs.d(TAG, "get id:%s", e.toString());
		}
		return getDefaultValue(type, id);
	}

	private static Object getDefaultValue(ValueType type, int id) {
		switch (type) {
		case DIMENSION:
			return getResource().getDimensionPixelOffset(id);
		case COLOR:
			return getResource().getColor(id);
		case DRAWABLE_RESOURCE:
			return id;
		case DRAWABLE:
			return getResource().getDrawable(id);

		default:
			break;
		}
		return 0;
	}

	private static Resources getResource() {
		return context.getResources();
	}

	private static Resources getCurrentResource() {
		return currentThemeContext.getResources();
	}

	//	@SuppressLint("NewApi")
	//	public static int getColor(int id) {
	//		if (getCurrentThemeId() == null || getCurrentThemeId().equals(context.getPackageName())) {
	//			Logs.d(TAG, "get defualt color by id:%s", id);
	//			return getDefaultColor(id);
	//		}
	//
	//		if (resourceCaches.get(id) != null) {
	//			Logs.d(TAG, "get cache color by id:%s", id);
	//			return resourceCaches.get(id).get();
	//		}
	//		try {
	//			String colorString = null;
	//			String COLOR_CLASS_NAME = COLOR_CLASS;
	//			Class<?> tempClass = Class.forName(context.getPackageName() + COLOR_CLASS_NAME);
	//			Field[] fields = tempClass.getFields();
	//			int size = fields.length;
	//			for (int i = 0; i < size; i++) {
	//				int value = fields[i].getInt(null);
	//				if (id == value) {
	//					colorString = fields[i].getName();
	//					Logs.d(TAG, "find color string:%s by id:%s", colorString, id);
	//				}
	//			}
	//
	//			//		PathClassLoader pathClassLoader = new PathClassLoader("/data/app/cn.woblog.android.test.switchtheme.theme.blue-1.apk", ClassLoader.getSystemClassLoader());
	//			PathClassLoader pathClassLoader = new PathClassLoader(getCurrentThemePath(), ClassLoader.getSystemClassLoader());
	//			Class<?> loadClass = pathClassLoader.loadClass(getCurrentThemeId() + COLOR_CLASS);
	//			fields = loadClass.getFields();
	//			int length = fields.length;
	//			int tempId = 0;
	//			for (int i = 0; i < length; i++) {
	//				if (fields[i].getName().equals(colorString)) {
	//					tempId = fields[i].getInt(null);
	//					//					Log.d(TAG, "color " + tempId + ":" + fields[i].getName());
	//					int color = currentThemeContext.getResources().getColor(tempId);
	//					resourceCaches.put(id, new SoftReference<Integer>(color));
	//					Logs.d(TAG, "find color string:%s id value:%d color:%d", colorString, tempId, color);
	//					return color;
	//				}
	//			}
	//		} catch (Exception e) {
	//			e.printStackTrace();
	//			Logs.d(TAG, "get id:%s", e.getLocalizedMessage());
	//		}
	//		return getDefaultColor(id);
	//	}

	//	private static String getCurrentThemePath() {
	//		//		return (APK_DIR + getCurrentThemeId() + APK_FILENAME);
	//		return getCurrentThemeId();
	//
	//	}

	public static boolean isRefreshUI() {
		//		return (firstThemePackageName == null) ? false : (!firstThemePackageName.equals(getCurrentThemeId()));
		//		return (firstThemePackageName == null) ? false : (!firstThemePackageName.equals(()));
		if (getCurrentThemeId() == null) {
			return false;
		}
		return !firstThemePackageName.equals(getCurrentThemeId());
	}

	public static void setRefreshUI() {
		firstThemePackageName = getCurrentThemeId();
	}
}
